package cc.rengu.oltp.service.base;

import cc.rengu.jradp.service.dubbo.Dubbo;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.utility.annotation.BIZ_PROCESS;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.threadarea.ThreadVar;
import com.alibaba.fastjson.JSON;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Optional;

/**
 * Created by 王成 on 2020/3/12
 */
public class DubboAsynBaseService extends RadpService {
    @Override
    protected int bizInit(String s) {
        return 0;
    }

    @Override
    protected int bizProcess(String s, int i) {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        try {
            String dubboServiceName = xmlTreeUtil.isExist(TreeNodeConstant.DUBBO_ASYN_FLAG) ?
                    xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.DUBBO_CLASS_NAME) :
                    xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.DUBBO_BEAN_NAME);
            if (StringUtil.isEmptyOrNull(dubboServiceName)) {
                rglog.error("Dubbo异步调用服务名为空!");
                return -1;
            }
            Object interfaceService = xmlTreeUtil.isExist(TreeNodeConstant.DUBBO_ASYN_FLAG) ?
                    Class.forName(dubboServiceName).newInstance() : Dubbo.getBean(dubboServiceName);

            if (xmlTreeUtil.isExist(TreeNodeConstant.DUBBO_ASYN_FLAG)) {
                ThreadVar.setVar("DUBBO_INNER_CALL_FLAG", "true");
            }

            String dubboMethod = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.DUBBO_METHOD_NAME);
            Method[] methods = interfaceService.getClass().getDeclaredMethods();
            Optional<Method> methodOpt = Arrays.stream(methods).filter(item -> item.getName().equals(dubboMethod)).findFirst();
            if (methodOpt.isPresent()) {
                Class<?> clasz = methodOpt.get().getParameterTypes()[0];
                Object dubboRequest = xmlTreeUtil.getXmlTreeObjectValue(TreeNodeConstant.DUBBO_REQUEST, clasz);
                Object dubboResponse = methodOpt.get().invoke(interfaceService, dubboRequest);
                rglog.debug("dubbo异步调用结果：{}", JSON.toJSONString(dubboResponse));
                xmlTreeUtil.setXmlTreeObjectValue(TreeNodeConstant.DUBBO_RESPONSE, dubboResponse);
                /* Step3：加载用户自定义的其它缓存信息 */
                invokeBizAnnoMethod(BIZ_PROCESS.class);
            } else {
                rglog.error("远程Dubbo服务<{}>无<{}>方法!", dubboServiceName, dubboMethod);
                return -1;
            }
        } catch (Exception e) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            e.printStackTrace(new PrintWriter(byteArrayOutputStream, true));
            rglog.error("Dubbo异步服务调用异常:<{}>", byteArrayOutputStream.toString());
            return -1;
        } finally {
            if (xmlTreeUtil.isExist(TreeNodeConstant.DUBBO_ASYN_FLAG)) {
                ThreadVar.removeVar("DUBBO_INNER_CALL_FLAG");
                xmlTreeUtil.deleteXmlTreeNode(TreeNodeConstant.DUBBO_ASYN_FLAG);
            }
        }
        return 0;
    }

    @Override
    protected int bizTerminate(String s) {
        return 0;
    }
}
